const { ethers } = require('ethers');
require('dotenv').config();

/**
 * IPFS URI 测试脚本
 * 用于验证正确的URI配置和访问方式
 */

// 配置信息
const CONFIG = {
    // 你的IPFS文件夹hash
    ipfsFolderHash: "QmYP7zPrdxLPeJ4h3YghxYZ7YYn3dYjF1R25TxfG9cG3jn",

    // 你的metadata文件hash
    metadataHash: "QmbQuC2AunXG1RyDyfkTrL4SyGQ6zurNzBag8zeFxALXkK",

    // 网络配置
    rpcUrl: process.env.SEPOLIA_RPC_URL,
    privateKey: process.env.PRIVATE_KEY,

    // 合约地址（部署后替换）
    contractAddress: "YOUR_CONTRACT_ADDRESS_HERE"
};

// 合约ABI（简化版）
const CONTRACT_ABI = [
    "function mintNFT(address to, string memory _tokenURI) public payable returns (uint256)",
    "function tokenURI(uint256 tokenId) public view returns (string)",
    "function setBaseURI(string memory newBaseURI) public",
    "function baseURI() public view returns (string)",
    "function totalSupply() public view returns (uint256)",
    "function ownerOf(uint256 tokenId) public view returns (address)"
];

class IPFSURITester {
    constructor() {
        this.provider = null;
        this.wallet = null;
        this.contract = null;
    }

    async initialize() {
        console.log("🚀 初始化IPFS URI测试器...");

        // 初始化provider和wallet
        this.provider = new ethers.providers.JsonRpcProvider(CONFIG.rpcUrl);
        this.wallet = new ethers.Wallet(CONFIG.privateKey, this.provider);

        // 初始化合约
        this.contract = new ethers.Contract(
            CONFIG.contractAddress,
            CONTRACT_ABI,
            this.wallet
        );

        console.log("✅ 初始化完成");
        console.log(`📝 钱包地址: ${this.wallet.address}`);
        console.log(`🔗 合约地址: ${CONFIG.contractAddress}`);
    }

    /**
     * 测试方案1: 使用完整的IPFS URI
     */
    async testFullIPFSUri() {
        console.log("\n🧪 测试方案1: 使用完整的IPFS URI");

        try {
            const fullUri = `ipfs://${CONFIG.metadataHash}`;
            console.log(`📤 铸造URI: ${fullUri}`);

            // 铸造NFT
            const tx = await this.contract.mintNFT(
                this.wallet.address,
                fullUri,
                { value: ethers.utils.parseEther("0") } // 免费铸造
            );

            console.log(`⏳ 交易哈希: ${tx.hash}`);
            await tx.wait();
            console.log("✅ 铸造成功");

            // 查询tokenURI
            const totalSupply = await this.contract.totalSupply();
            const tokenId = totalSupply.toNumber();
            const tokenURI = await this.contract.tokenURI(tokenId);

            console.log(`🆔 Token ID: ${tokenId}`);
            console.log(`🔗 最终URI: ${tokenURI}`);

            // 验证URI是否正确
            if (tokenURI === fullUri) {
                console.log("✅ URI验证成功！");
                return { success: true, tokenId, tokenURI };
            } else {
                console.log("❌ URI验证失败！");
                return { success: false, tokenId, tokenURI };
            }

        } catch (error) {
            console.error("❌ 方案1测试失败:", error.message);
            return { success: false, error: error.message };
        }
    }

    /**
     * 测试方案2: 使用baseURI + 文件名
     */
    async testBaseURIWithFilename() {
        console.log("\n🧪 测试方案2: 使用baseURI + 文件名");

        try {
            // 设置baseURI
            const baseURI = `ipfs://${CONFIG.ipfsFolderHash}/`;
            console.log(`🔧 设置baseURI: ${baseURI}`);

            const setBaseTx = await this.contract.setBaseURI(baseURI);
            await setBaseTx.wait();
            console.log("✅ baseURI设置成功");

            // 验证baseURI
            const currentBaseURI = await this.contract.baseURI();
            console.log(`📋 当前baseURI: ${currentBaseURI}`);

            // 铸造NFT（使用文件名）
            const filename = "metadata/1.json";
            console.log(`📤 铸造文件名: ${filename}`);

            const tx = await this.contract.mintNFT(
                this.wallet.address,
                filename,
                { value: ethers.utils.parseEther("0") }
            );

            console.log(`⏳ 交易哈希: ${tx.hash}`);
            await tx.wait();
            console.log("✅ 铸造成功");

            // 查询tokenURI
            const totalSupply = await this.contract.totalSupply();
            const tokenId = totalSupply.toNumber();
            const tokenURI = await this.contract.tokenURI(tokenId);

            console.log(`🆔 Token ID: ${tokenId}`);
            console.log(`🔗 最终URI: ${tokenURI}`);

            // 验证URI是否正确
            const expectedURI = `${baseURI}${filename}`;
            if (tokenURI === expectedURI) {
                console.log("✅ URI验证成功！");
                return { success: true, tokenId, tokenURI };
            } else {
                console.log("❌ URI验证失败！");
                console.log(`预期: ${expectedURI}`);
                console.log(`实际: ${tokenURI}`);
                return { success: false, tokenId, tokenURI };
            }

        } catch (error) {
            console.error("❌ 方案2测试失败:", error.message);
            return { success: false, error: error.message };
        }
    }

    /**
     * 测试IPFS URI访问
     */
    async testIPFSAccess() {
        console.log("\n🌐 测试IPFS URI访问");

        const testURIs = [
            `ipfs://${CONFIG.metadataHash}`,
            `ipfs://${CONFIG.ipfsFolderHash}/metadata/1.json`,
            `https://ipfs.io/ipfs/${CONFIG.metadataHash}`,
            `https://gateway.pinata.cloud/ipfs/${CONFIG.metadataHash}`
        ];

        for (const uri of testURIs) {
            console.log(`\n🔍 测试URI: ${uri}`);

            try {
                // 这里可以添加实际的HTTP请求测试
                console.log("💡 提示: 你可以在浏览器中访问以下URL来测试:");
                if (uri.startsWith('ipfs://')) {
                    const hash = uri.replace('ipfs://', '');
                    console.log(`   - https://ipfs.io/ipfs/${hash}`);
                    console.log(`   - https://gateway.pinata.cloud/ipfs/${hash}`);
                    console.log(`   - https://cloudflare-ipfs.com/ipfs/${hash}`);
                }
            } catch (error) {
                console.error(`❌ 访问失败: ${error.message}`);
            }
        }
    }

    /**
     * 运行所有测试
     */
    async runAllTests() {
        console.log("🎯 开始IPFS URI测试...\n");

        // 检查配置
        if (CONFIG.contractAddress === "YOUR_CONTRACT_ADDRESS_HERE") {
            console.error("❌ 请先设置正确的合约地址！");
            return;
        }

        await this.initialize();

        // 运行测试
        const result1 = await this.testFullIPFSUri();
        const result2 = await this.testBaseURIWithFilename();
        await this.testIPFSAccess();

        // 总结
        console.log("\n📊 测试结果总结:");
        console.log(`方案1 (完整URI): ${result1.success ? '✅ 成功' : '❌ 失败'}`);
        console.log(`方案2 (baseURI): ${result2.success ? '✅ 成功' : '❌ 失败'}`);

        if (result1.success && result2.success) {
            console.log("\n🎉 所有测试通过！你的IPFS URI配置正确。");
        } else {
            console.log("\n⚠️  部分测试失败，请检查配置。");
        }
    }
}

// 使用说明
function printUsage() {
    console.log(`
🔧 IPFS URI 测试脚本使用说明

📋 使用前准备:
1. 确保已部署NFT合约
2. 在CONFIG中设置正确的合约地址
3. 确保.env文件包含正确的私钥和RPC URL

🚀 运行测试:
node ipfs-uri-test.js

📝 测试内容:
- 方案1: 使用完整的IPFS URI铸造
- 方案2: 使用baseURI + 文件名铸造
- IPFS URI访问测试

💡 推荐方案:
- 如果每个NFT有独特的metadata，使用方案1
- 如果所有NFT使用相同的文件夹结构，使用方案2
    `);
}

// 主函数
async function main() {
    if (process.argv.includes('--help') || process.argv.includes('-h')) {
        printUsage();
        return;
    }

    const tester = new IPFSURITester();
    await tester.runAllTests();
}

// 如果直接运行此脚本
if (require.main === module) {
    main().catch(console.error);
}

module.exports = IPFSURITester;
